package com.biz.primus.ms.commodity.service;

import com.biz.primus.base.enums.commodity.IStatus;
import com.biz.primus.base.exception.utils.AssertUtils;
import com.biz.primus.commodity.exception.CommodityExceptionType;
import com.biz.primus.commodity.vo.CommodityCustomModelVo;
import com.biz.primus.common.utils.CopyUtils;
import com.biz.primus.ms.commodity.dao.po.CommodityCustomModel;
import com.biz.primus.ms.commodity.dao.po.Product;
import com.biz.primus.ms.commodity.dao.redis.ProductRedisDao;
import com.biz.primus.ms.commodity.dao.repository.custom.CommodityCustomModelRepository;
import com.biz.primus.ms.commodity.dao.repository.product.ProductRepository;
import com.biz.primus.ms.commodity.service.frontend.AbstractCommodityService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;


@Slf4j
@Service
public class CommodityCustomModelService extends AbstractCommodityService {

    @Autowired
    private CommodityCustomModelRepository commodityCustomModelRepository;

    @Autowired
    private ProductRepository productRepository;

    @Autowired
    private ProductRedisDao productRedisDao;

    public CommodityCustomModel create() {
        CommodityCustomModelVo respVo = new CommodityCustomModelVo();
        respVo.setStatus(IStatus.DELETE);
        CommodityCustomModel commodityCustomModel = new CommodityCustomModel();
        CopyUtils.copyProperties(respVo, commodityCustomModel);
        CommodityCustomModel save = commodityCustomModelRepository.save(commodityCustomModel);
        respVo.setId(String.valueOf(save.getId()));
        return save;
    }

    @Transactional(rollbackFor = Exception.class)
    public void update(CommodityCustomModelVo reqVo) {
        CommodityCustomModel commodityCustomModel = commodityCustomModelRepository.findOne(Long.valueOf(reqVo.getId()));
        relieve(commodityCustomModel);
        bind(reqVo, commodityCustomModel);

        CopyUtils.copyProperties(reqVo, commodityCustomModel);
        commodityCustomModelRepository.save(commodityCustomModel);
    }

    private void bind(CommodityCustomModelVo reqVo, CommodityCustomModel commodityCustomModel) {
        if (CollectionUtils.isNotEmpty(reqVo.getProductCodes())) {
            List<Product> products = productRepository.findByProductCodeIn(reqVo.getProductCodes());
            products.forEach((Product product) -> {
                product.setCommodityCustomModel(commodityCustomModel);
                productRedisDao.setCustomModel(product.getProductCode(), commodityCustomModel.getRichText());
            });
            commodityCustomModel.setProducts(products);
        }
        if (reqVo.getCategoryId() != null) {
            productRedisDao.setCustomModel(commodityCustomModel.getCategoryId().toString(), commodityCustomModel.getRichText());
        }
    }

    private void relieve(CommodityCustomModel commodityCustomModel) {
        if (CollectionUtils.isNotEmpty(commodityCustomModel.getProducts())) {
            List<Product> products = commodityCustomModel.getProducts();
            products.forEach((Product product) -> {
                product.setCommodityCustomModel(null);
                productRedisDao.setCustomModel(product.getProductCode(), "");
            });
            productRepository.save(products);
        }
        if (commodityCustomModel.getCategoryId() != null) {
            productRedisDao.setCustomModel(commodityCustomModel.getCategoryId().toString(), "");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateStatus(Long modelId, IStatus status) {
        CommodityCustomModel one = commodityCustomModelRepository.findOne(modelId);
        AssertUtils.notNull(one, CommodityExceptionType.COMMON_EXCEPTION, "自定义模型不存在");
        one.setStatus(status);

        commodityCustomModelRepository.save(one);
        this.delayer.executeAfterTransactionCommit(() -> this.refreshRedis(one));
    }

    public void refreshRedis(CommodityCustomModel one) {
        if (CollectionUtils.isNotEmpty(one.getProducts())) {
            one.getProducts().forEach((Product product) -> {
                productRedisDao.setCustomModel(product.getProductCode(), one.getRichText());
            });
            if (one.getCategoryId() != null) {
                productRedisDao.setCustomModel(one.getCategoryId().toString(), one.getRichText());
            }
        }
    }

}
